package com.tom.happy.mrs.chicken;

import android.animation.Animator;
import android.animation.AnimatorListenerAdapter;
import android.animation.FloatEvaluator;
import android.animation.Keyframe;
import android.animation.ObjectAnimator;
import android.animation.PropertyValuesHolder;
import android.animation.ValueAnimator;
import android.app.Activity;
import android.app.Fragment;
import android.content.Context;
import android.content.SharedPreferences;
import android.graphics.Rect;
import android.graphics.drawable.AnimationDrawable;
import android.media.AudioManager;
import android.media.SoundPool;
import android.os.Bundle;
import android.os.Handler;
import android.os.Message;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.view.animation.AccelerateDecelerateInterpolator;
import android.view.animation.DecelerateInterpolator;
import android.widget.ImageButton;
import android.widget.ImageView;
import android.widget.TextView;

import java.lang.ref.WeakReference;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Random;
import java.util.Stack;

public abstract class BaseFragment extends Fragment {
    protected final static String PREFS_NAME = "my_prefs";
    // 单房子抓到的小鸡数.
    protected final static String PREFS_COOP_ONE = "coop_one";
    // 双房子抓到的小鸡数.
    protected final static String PREFS_COOP_ONE_COUNTER = "coop_one_counter";
    // 单房子计时赛抓到的小鸡数.
    protected final static String PREFS_COOP_TWO = "coop_two";
    // 双房子计时赛抓到的小鸡数.
    protected final static String PREFS_COOP_TWO_COUNTER = "coop_two_counter";
    // 小鸡下蛋数
    protected final static String PREFS_LAY_EGGS = "lay_eggs";

    protected int mLayoutResID = -1;
    protected Context mContext;
    protected MyHandler mHandler;

    protected final static int MSG_MOVE_TO_POS = 0;
    protected final static int MSG_LAY_EGG = 1;
    protected final static int MSG_EGG_BROKEN = 2;
    protected final static int MSG_HATCH_CHICKEN = 3;
    protected final static int MSG_PLAY_CHICKEN_RING = 4;
    protected final static int MSG_CHICKEN_LEAVE = 5;
    protected final static int MSG_MOTHER_CRY = 6;
    protected TextView mCatchCountView;
    protected ImageView mMother;
    protected int mCatchCount;
    private Rect mTmpRect = new Rect();

    private int[] mTmpLoc = new int[2];
    protected Random mRandom;
    // 屏幕宽高
    protected int mDisplayWidth;
    protected int mDisplayHeight;
    // 母鸡宽
    protected int mMotherWidth;

    // 鸡蛋宽
    protected int mEggWidth;
    protected ViewGroup mLayoutView;
    // 可用鸡蛋记录
    private ArrayList<ImageView> mAvailableEggs = new ArrayList<ImageView>();

    protected int mCurrentChickens;
    protected SoundPool mSoundPool;
    protected HashMap<Integer, Integer> mSoundID = new HashMap<Integer, Integer>();

    // 记录之前的下蛋位置, 以及对应鸡蛋颜色
    HashMap<ImageView, Boolean> mEggColorMaps = new HashMap<ImageView, Boolean>();
    HashMap<ImageView, ObjectAnimator> mEggAnims = new HashMap<ImageView, ObjectAnimator>();
    // 1-单房子抓小鸡; 2-单房子抓小鸡计时; 3-双房子; 4-双房子计时
    // 0-小鸡下蛋游戏.
    protected int mGameType;
    public static final int GAME_TYPE_LAY_EGGS = 0;
    public static final int GAME_TYPE_COOP_ONE = 1;
    public static final int GAME_TYPE_COOP_ONE_COUNTER = 2;
    public static final int GAME_TYPE_COOP_TWO = 3;
    public static final int GAME_TYPE_COOP_TWO_COUNTER = 4;

    // 母鸡移动速度
    private float mMotherSpeed = 800f;
    // 母鸡移动速度
    private float mChickenSpeed = 200f;

    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
        mLayoutView = (ViewGroup) inflater.inflate(mLayoutResID, container, false);
        mContext = getActivity();
        mHandler = new MyHandler(getActivity());

        mMotherWidth = DensityUtils.dip2px(mContext, 100);
        mEggWidth = DensityUtils.dip2px(mContext, 60);
        mMotherSpeed = DensityUtils.dip2px(mContext, 400);
        mChickenSpeed = DensityUtils.dip2px(mContext, 100);

        mSoundPool = new SoundPool(10, AudioManager.STREAM_MUSIC, 5);
        mSoundID.put(com.tom.happy.mrs.chicken.R.raw.chicken, mSoundPool.load(mContext, com.tom.happy.mrs.chicken.R.raw.chicken, 1));
        mSoundID.put(com.tom.happy.mrs.chicken.R.raw.lay_egg, mSoundPool.load(mContext, com.tom.happy.mrs.chicken.R.raw.lay_egg, 1));
        mSoundID.put(com.tom.happy.mrs.chicken.R.raw.egg_crack, mSoundPool.load(mContext, com.tom.happy.mrs.chicken.R.raw.egg_crack, 1));
        mSoundID.put(com.tom.happy.mrs.chicken.R.raw.baby_chick, mSoundPool.load(mContext, com.tom.happy.mrs.chicken.R.raw.baby_chick, 1));
        mSoundID.put(com.tom.happy.mrs.chicken.R.raw.crush, mSoundPool.load(mContext, com.tom.happy.mrs.chicken.R.raw.crush, 1));

        mDisplayWidth = getResources().getDisplayMetrics().widthPixels;
        mDisplayHeight = getResources().getDisplayMetrics().heightPixels;

        mRandom = new Random();

        mMother = (ImageView) mLayoutView.findViewById(com.tom.happy.mrs.chicken.R.id.y_mother);
        mCatchCountView = (TextView) mLayoutView.findViewById(com.tom.happy.mrs.chicken.R.id.catch_count);

        ImageButton quitView = (ImageButton) mLayoutView.findViewById(com.tom.happy.mrs.chicken.R.id.quit);
        ((AnimationDrawable) quitView.getBackground()).start();
        quitView.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                ((MainActivity)getActivity()).showConformDialog();
            }
        });
        mGameType = ((MainActivity) getActivity()).mGameType;

        return mLayoutView;
    }

    @Override
    public void onPause() {
        super.onPause();
        // 保存当前小鸡数;
        saveCount(mCatchCount);
        mHandler.removeMessages(MSG_PLAY_CHICKEN_RING);
        mSoundPool.autoPause();
        mHandler.pause();
    }

    @Override
    public void onResume() {
        super.onResume();
        // 恢复当前小鸡数;
        // mCatchCount = getSavedCount(mGameType);
        mCatchCountView.setText("" + mCatchCount);

        if (mMother.getBackground() instanceof AnimationDrawable) {
            ((AnimationDrawable) mMother.getBackground()).start();
        }
        if (this instanceof LayEggsFragment) {
            mHandler.removeMessages(MSG_MOTHER_CRY);
            mHandler.sendMessageDelayed(mHandler.obtainMessage(MSG_MOTHER_CRY), 2400);
        }
        mSoundPool.autoResume();
        mHandler.resume();
    }

    /**
     * 指定位置下一个蛋
     *
     * @param targetX
     * @param targetY
     */
    private void layEgg(int targetX, int targetY) {
        ImageView egg;
        //放置一个鸡蛋
        if (mAvailableEggs.size() > 0) {
            egg = mAvailableEggs.remove(0);
            egg.setOnClickListener(null);
            egg.bringToFront();
        } else {
            egg = new ImageView(mContext);
            egg.setLayoutParams(new ViewGroup.LayoutParams(mEggWidth, mEggWidth));
            egg.setVisibility(View.GONE);
            mLayoutView.addView(egg);
        }

        // 下蛋游戏鸡蛋全是黄色的
        boolean isYellow = this instanceof ChickenCoopFragment ? mRandom.nextBoolean() : true;
        egg.setBackgroundResource(isYellow ? com.tom.happy.mrs.chicken.R.drawable.y_egg_01 : com.tom.happy.mrs.chicken.R.drawable.b_egg_01);
        egg.setX(targetX);
        egg.setY(targetY);
        egg.setVisibility(View.VISIBLE);

        // 下蛋动画
        ObjectAnimator animator = ObjectAnimator.ofPropertyValuesHolder(egg, pvhRotate).setDuration(500);
        animator.start();

        mEggColorMaps.put(egg, isYellow);
        mMother.bringToFront();

        // 当前总的鸡蛋数.
        mCurrentChickens++;

        playMotherLayAnim(mMother);

        // 播放音效
        mSoundPool.play(mSoundID.get(com.tom.happy.mrs.chicken.R.raw.lay_egg), 1, 1, 0, 0, 1);

        Message msg = mHandler.obtainMessage(MSG_EGG_BROKEN);
        msg.obj = egg;
        mHandler.sendMessageDelayed(msg, 3000);

        if (this instanceof LayEggsFragment) {
            mCatchCount++;
            mCatchCountView.setText("" + mCatchCount);
        }
    }

    /**
     * @param mother
     * @param targetX 目标位置x
     * @param targetY 目标位置y
     */
    protected void moveMotherToPos(final ImageView mother, final float targetX, final float targetY, final boolean needLayEgg) {
        final float oriX = mother.getX();
        final float oriY = mother.getY();
        final float offsetX = targetX - oriX;
        final float offsetY = targetY - oriY;
        if (offsetX > 0) {
            mother.setRotationY(180);
        } else {
            mother.setRotationY(0);
        }
        final ValueAnimator anim = ValueAnimator.ofFloat(0f, 1f);
        anim.setDuration((long) (Math.abs(offsetX / mMotherSpeed) * 1000));
        anim.setInterpolator(new DecelerateInterpolator());
        anim.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
            @Override
            public void onAnimationUpdate(ValueAnimator animation) {
                float value = ((Float) animation.getAnimatedValue()).floatValue();
                mother.setX(oriX + value * offsetX);
                mother.setY(oriY + value * offsetY);
            }
        });

        anim.addListener(new AnimatorListenerAdapter() {
            @Override
            public void onAnimationEnd(Animator animation) {
                if (needLayEgg) {
                    Message msg = mHandler.obtainMessage(MSG_LAY_EGG);
                    msg.arg1 = (int) targetX + (mMotherWidth - mEggWidth) / 2;
                    msg.arg2 = (int) targetY + mMotherWidth - mEggWidth;
                    mHandler.sendMessage(msg);
                } else {
                    mother.setBackgroundResource(com.tom.happy.mrs.chicken.R.drawable.y_chicken_mother_anim);
                    ((AnimationDrawable) mother.getBackground()).start();
                }
            }
        });
        anim.start();
    }

    // 鸡妈妈下蛋动画
    private void playMotherLayAnim(final ImageView mother) {
        final float oriY = mother.getY();

        //ObjectAnimator anim = ObjectAnimator.ofObject(mother, View.TRANSLATION_Y.getName(), new FloatEvaluator(), 0, 1.0, 0);
        final ValueAnimator anim = ValueAnimator.ofFloat(0f, 1.0f, 0f);
        anim.setDuration(450);
        anim.setInterpolator(new AccelerateDecelerateInterpolator());
        anim.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
            @Override
            public void onAnimationUpdate(ValueAnimator animation) {
                float currentValue = ((Float) animation.getAnimatedValue()).floatValue();
                mother.setY(oriY - currentValue * mother.getHeight());
            }
        });
        anim.addListener(new AnimatorListenerAdapter() {
            @Override
            public void onAnimationStart(Animator animation) {
                super.onAnimationStart(animation);
                mother.setBackgroundResource(com.tom.happy.mrs.chicken.R.drawable.mrs_chicken_up);
            }

            @Override
            public void onAnimationEnd(Animator animation) {
                super.onAnimationEnd(animation);
                mother.setBackgroundResource(com.tom.happy.mrs.chicken.R.drawable.y_chicken_normal);
                onMotherAnimEnd();
            }
        });
        anim.start();
    }

    public abstract void onMotherAnimEnd();

    /**
     * 移除小鸡.
     *
     * @param view
     */
    protected void hideChicken(ImageView view) {
        synchronized (this) {
            mCurrentChickens--;
            view.setOnTouchListener(null);
            view.setVisibility(View.GONE);
            mEggColorMaps.remove(view);
            mAvailableEggs.add(view);
        }
    }

    protected void moveChickenToOriPos(ImageView v, float oriX, float oriY) {
        if (oriX != 0 && oriY != 0) {
            v.setX(oriX);
            v.setY(oriY);
        }
        // 添加小鸡离开动画
        addChickenLeaveAnim(v);
    }

    protected void addChickenLeaveAnim(ImageView view) {
        final ImageView chicken = view;
        float posX = chicken.getX();
        float moveDistance;
        float targetX;
        if (posX < mDisplayWidth / 2) {
            chicken.setRotationY(0);
            moveDistance = posX + mEggWidth;
            targetX = -mEggWidth;
        } else {
            chicken.setRotationY(180);
            moveDistance = mDisplayWidth - posX;
            targetX = mDisplayWidth;
        }
        ObjectAnimator animator = ObjectAnimator.ofObject(chicken, View.TRANSLATION_X.getName(), new FloatEvaluator(), targetX);
        animator.setDuration((long) ((moveDistance / mChickenSpeed) * 1000));
        animator.addListener(new AnimatorListenerAdapter() {
            @Override
            public void onAnimationEnd(Animator animation) {
                hideChicken(chicken);
            }

            @Override
            public void onAnimationCancel(Animator animation) {
                super.onAnimationCancel(animation);
                Log.e("12345", "cancel");
            }
        });
        mEggAnims.put(view, animator);
        animator.start();
    }

    protected void cancelChickenLeaveAnim(ImageView view) {
        synchronized (getActivity()) {
            if (mHandler.hasMessages(MSG_CHICKEN_LEAVE, view)) {
                mHandler.removeMessages(MSG_CHICKEN_LEAVE, view);
            }
            if (mEggAnims.containsKey(view)) {
                mEggAnims.get(view).removeAllListeners();
                mEggAnims.get(view).cancel();
            }
        }
    }

    int degree = 5;
    final PropertyValuesHolder pvhRotate = PropertyValuesHolder.ofKeyframe(View.ROTATION,
            Keyframe.ofFloat(0f, 0f),
            Keyframe.ofFloat(.2f, -degree),
            Keyframe.ofFloat(.4f, degree),
            Keyframe.ofFloat(.6f, -degree),
            Keyframe.ofFloat(.8f, degree),
            Keyframe.ofFloat(1f, 0)
    );

    private void breakEgg(final Message msg) {
        final ImageView egg = (ImageView) msg.obj;
        ObjectAnimator animator = ObjectAnimator.ofPropertyValuesHolder(egg, pvhRotate).setDuration(1000);
        animator.addListener(new AnimatorListenerAdapter() {
            @Override
            public void onAnimationEnd(Animator animation) {
                boolean isYellow = mEggColorMaps.get(egg);
                egg.setBackgroundResource(isYellow ? com.tom.happy.mrs.chicken.R.drawable.y_egg_02 : com.tom.happy.mrs.chicken.R.drawable.b_egg_02);
                Message newMsg = mHandler.obtainMessage(MSG_HATCH_CHICKEN, egg);
                mHandler.sendMessageDelayed(newMsg, 2000);
            }
        });
        animator.start();
    }

    private void hatchChicken(final Message msg) {
        final ImageView egg = (ImageView) msg.obj;
        egg.bringToFront();
        mMother.bringToFront();
        ObjectAnimator animator = ObjectAnimator.ofPropertyValuesHolder(egg, pvhRotate).setDuration(1000);
        animator.addListener(new AnimatorListenerAdapter() {
            @Override
            public void onAnimationEnd(Animator animation) {
                mSoundPool.play(mSoundID.get(com.tom.happy.mrs.chicken.R.raw.egg_crack), 1, 1, 0, 0, 1);
                boolean isYellow = mEggColorMaps.get(egg);
                egg.setBackgroundResource(isYellow ? com.tom.happy.mrs.chicken.R.drawable.y_chicken_anim : com.tom.happy.mrs.chicken.R.drawable.b_chicken_anim);
                ((AnimationDrawable) egg.getBackground()).start();
                Message newMsg = mHandler.obtainMessage(MSG_PLAY_CHICKEN_RING, egg);
                mHandler.sendMessageDelayed(newMsg, 1200);
                if (getTouchListener() != null) {
                    egg.setOnTouchListener(getTouchListener());
                }

                Message newMsg1 = mHandler.obtainMessage(MSG_CHICKEN_LEAVE, egg);
                mHandler.sendMessageDelayed(newMsg1, 5000);
            }
        });
        animator.start();
    }

    protected View.OnTouchListener getTouchListener() {
        return null;
    }

    protected int getSavedCount(int gameType) {
        SharedPreferences prefs = mContext.getSharedPreferences(PREFS_NAME, Context.MODE_PRIVATE);
        int count = 0;
        switch (gameType) {
            case GAME_TYPE_LAY_EGGS:
                count = prefs.getInt(PREFS_LAY_EGGS, 0);
                break;
            case GAME_TYPE_COOP_ONE:
                count = prefs.getInt(PREFS_COOP_ONE, 0);
                break;
            case GAME_TYPE_COOP_ONE_COUNTER:
                count = prefs.getInt(PREFS_COOP_ONE_COUNTER, 0);
                break;
            case GAME_TYPE_COOP_TWO:
                count = prefs.getInt(PREFS_COOP_TWO, 0);
                break;
            case GAME_TYPE_COOP_TWO_COUNTER:
                count = prefs.getInt(PREFS_COOP_TWO_COUNTER, 0);
                break;

        }
        return count;
    }

    protected void saveCount(int count) {
//        SharedPreferences.Editor editor = mContext.getSharedPreferences(PREFS_NAME, Context.MODE_PRIVATE).edit();
//        switch (mGameType) {
//            case GAME_TYPE_LAY_EGGS:
//                editor.putInt(PREFS_LAY_EGGS, count);
//                break;
//            case GAME_TYPE_COOP_ONE:
//                editor.putInt(PREFS_COOP_ONE, count);
//                break;
//            case GAME_TYPE_COOP_ONE_COUNTER:
//                editor.putInt(PREFS_COOP_ONE_COUNTER, count);
//                break;
//            case GAME_TYPE_COOP_TWO:
//                editor.putInt(PREFS_COOP_TWO, count);
//                break;
//            case GAME_TYPE_COOP_TWO_COUNTER:
//                editor.putInt(PREFS_COOP_TWO_COUNTER, count);
//                break;
//        }
//        editor.commit();
    }

    class MyHandler extends Handler {
        WeakReference<Activity> mWeakReference;
        Stack<Message> s = new Stack<Message>();
        boolean is_paused = false;

        public MyHandler(Activity activity) {
            mWeakReference = new WeakReference<Activity>(activity);
        }

        public synchronized void pause() {
            is_paused = true;
        }

        public synchronized void resume() {
            is_paused = false;
            while (!s.empty()) {
                sendMessageAtFrontOfQueue(s.pop());
            }
        }

        @Override
        public void handleMessage(Message msg) {
            final Activity activity = mWeakReference.get();
            if (activity != null) {
                if (is_paused) {
                    s.push(Message.obtain(msg));
                    return;
                } else {
                    switch (msg.what) {
                        case MSG_MOVE_TO_POS:
                            moveMotherToPos(mMother, msg.arg1, msg.arg2, true);
                            break;
                        case MSG_LAY_EGG:
                            layEgg(msg.arg1, msg.arg2);
                            break;
                        case MSG_EGG_BROKEN:
                            breakEgg(msg);
                            break;
                        case MSG_HATCH_CHICKEN:
                            hatchChicken(msg);
                            break;
                        case MSG_PLAY_CHICKEN_RING:
                            if (mEggColorMaps.containsKey(msg.obj)) {
                                mSoundPool.play(mSoundID.get(com.tom.happy.mrs.chicken.R.raw.baby_chick), 1, 1, 0, 0, 1);
                                sendMessageDelayed(mHandler.obtainMessage(MSG_PLAY_CHICKEN_RING, msg.obj), 2400);
                            }
                            break;
                        case MSG_CHICKEN_LEAVE:
                            addChickenLeaveAnim((ImageView) msg.obj);
                            break;
                        case MSG_MOTHER_CRY:
                            mSoundPool.play(mSoundID.get(R.raw.chicken), 1, 1, 0, 0, 1);
                            sendMessageDelayed(mHandler.obtainMessage(MSG_MOTHER_CRY), 2400);
                            break;
                        default:
                            break;
                    }
                }
            }
        }
    }
}
